﻿
using ELearning.BLL;
using ELearning.Common.Model;
using ELearning.Models;
using ELearning.Models.ViewModel.Menu;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using ELearning.Common;
using ELearning.Common.CommonStr;
using ELearning.Common.Extensions;

namespace ELearning.API.Controllers
{
    /// <summary>
    /// 菜单控制器
    /// </summary>
    public class MenuController : BaseApiController
    {
        /// <summary>
        /// 菜单操作service
        /// </summary>
        protected EMenuService MenuService = new EMenuService();

        /// <summary>
        /// 角色用户与菜单管理操作service
        /// </summary>
        private RMenuURService rMenuUrService = new RMenuURService();

        /// <summary>
        /// 角色操作service
        /// </summary>
        private ERoleService roleService = new ERoleService();

        /// <summary>
        /// 用户操作service
        /// </summary>
        private ESysUserService userService = new ESysUserService();

        /// <summary>
        /// 角色用户管理操作service
        /// </summary>
        private RRoleUserService roleUserService = new RRoleUserService();

        #region system
        /// <summary>
        /// 获取用户的菜单列表
        /// </summary>
        [HttpGet, Route("api/menu/GetUserMenuList")]
        public ServiceResponse<List<MenuViewModel>> GetUserMenuList()
        {
            string userId = CurrentUserModel.LoginName;
            var ls = MenuService.GetUserMenusByUserId(userId).ToList();
            var viewModels = new List<MenuViewModel>();
            GetMenuViewModels(viewModels, ls, Guid.Parse("73ee5679-2376-4ea1-9bcb-0915150846b2"));
            return ServiceResponse<List<MenuViewModel>>.SuccessResponse("success", viewModels);
        }
        #endregion

        /// <summary>
        /// 获取全部未分层级的菜单列表
        /// </summary>
        [HttpGet, Route("api/menu/GetMenuList")]
        public ServiceResponse<List<EMenu>> GetMenuList()
        {
            var ls = MenuService.FindList(m => !m.IsDelete).ToList();
            return ServiceResponse<List<EMenu>>.SuccessResponse("success", ls);
        }

        /// <summary>
        /// 获取平台下面的菜单列表
        /// </summary>
        [HttpPost, Route("api/menu/GetMenus")]
        public ServiceResponse<List<MenuViewModel>> GetMenus(GetMenusRequest request)
        {
            var ls = MenuService.GetSubMenusById(request.MenuId);
            //if(!string.IsNullOrEmpty(request.PlatformType))
            //    ls = MenuService.FindList(m => !m.IsDelete && m.PlatformType == request.PlatformType).ToList();
            var viewModels = new List<MenuViewModel>();
            GetMenuViewModels(viewModels, ls, Guid.Parse("00000000-0000-0000-0000-000000000000"));

            foreach (var viewModel in viewModels) //第一级菜单的父级名称赋值 /
            {
                viewModel.ParentName = "/";
            }

            return ServiceResponse<List<MenuViewModel>>.SuccessResponse("success", viewModels);
        }


        /// <summary>
        /// 获取层级分明的菜单列表
        /// </summary>
        [HttpGet, Route("api/menu/GetMenusItem")]
        public ServiceResponse<List<MenuViewModel>> GetMenusItem()
        {
            var ls = MenuService.FindList(m => !m.IsDelete).ToList();
            var viewModels = new List<MenuViewModel>();
            GetMenuViewModels(viewModels, ls, Guid.Parse("00000000-0000-0000-0000-000000000000"));

            foreach (var viewModel in viewModels) //第一级菜单的父级名称赋值 /
            {
                viewModel.ParentName = "/";
            }

            return ServiceResponse<List<MenuViewModel>>.SuccessResponse("success", viewModels);
        }

        /// <summary>
        /// 获取角色下面的菜单列表
        /// 角色授权--查看权限
        /// </summary>
        [HttpGet, Route("api/menu/GetRoleMenus")]
        public ServiceResponse<List<MenuViewModel>> GetRoleMenus(Guid roleId)
        {
            var roles = roleService.GetRoleParentList(roleId);
            var roleIds = roles.Select(r => r.RoleID).ToList();
            var menuIds = rMenuUrService.FindList(r => roleIds.Contains(r.KeyId)).Select(r => r.MenuId).ToList();

            var ls = MenuService.FindList(m => !m.IsDelete && menuIds.Contains(m.Id)).ToList();
            var viewModels = new List<MenuViewModel>();
            GetMenuViewModels(viewModels, ls, Guid.Parse("00000000-0000-0000-0000-000000000000"));

            foreach (var viewModel in viewModels) //第一级菜单的父级名称赋值 /
            {
                viewModel.ParentName = "/";
            }

            return ServiceResponse<List<MenuViewModel>>.SuccessResponse(CommonConst.OprateSuccessStr, viewModels);
        }

        /// <summary>
        /// 获取用户下面的菜单列表
        /// 个人授权--查看权限
        /// </summary>
        [HttpGet, Route("api/menu/GetUserMenus")]
        public ServiceResponse<List<MenuViewModel>> GetUserMenus(Guid userId)
        {
            var roleIds = roleUserService.FindList(r => r.UserID == userId).Select(r => r.RoleID).ToList();

            var menuIds = rMenuUrService.FindList(r => roleIds.Contains(r.KeyId)).Select(r => r.MenuId).ToList();

            var ls = MenuService.FindList(m => !m.IsDelete && menuIds.Contains(m.Id)).ToList();
            var viewModels = new List<MenuViewModel>();
            GetMenuViewModels(viewModels, ls, Guid.Parse("00000000-0000-0000-0000-000000000000"));

            foreach (var viewModel in viewModels) //第一级菜单的父级名称赋值 /
            {
                viewModel.ParentName = "/";
            }

            return ServiceResponse<List<MenuViewModel>>.SuccessResponse(CommonConst.OprateSuccessStr, viewModels);
        }

        /// <summary>
        /// 添加菜单
        /// </summary>
        [HttpPost, Route("api/menu/AddMenu")]
        public ServiceResponse<MenuViewModel> AddMenu(MenuViewModel viewModel)
        {
            var menu = new EMenu
            {
                Id = GuidUtil.NewSequentialId(),
                Affix = viewModel.Meta.Affix,
                Component = viewModel.Component,
                Icon = viewModel.Meta.Icon,
                IsDelete = false,
                IsUsed = true,
                Name = viewModel.Name,
                NoCache = viewModel.Meta.NoCache,
                ParentId = viewModel.ParentId,
                Path = viewModel.Path,
                Title = viewModel.Title,
                Code = viewModel.Code,
                Type = viewModel.Type,
                Redirect = viewModel.Redirect,
                Creater = CurrentUserModel.LoginName,
                CreateTime = DateTime.Now,
                Modifyer = CurrentUserModel.LoginName,
                ModifyTime = DateTime.Now,
                Sort = viewModel.Sort
            };
            var fullSpell = PinYinHelper.ConvertToAllSpell(viewModel.Title);//菜单全拼
            var firstSpell = PinYinHelper.GetFirstSpell(viewModel.Title);//菜单首拼
            var model = MenuService.Find(m => !m.IsDelete && m.Code.Equals(firstSpell, StringComparison.InvariantCultureIgnoreCase));
            if (model != null)
            {
                model = MenuService.Find(m => !m.IsDelete && m.Code.Equals(fullSpell, StringComparison.InvariantCultureIgnoreCase));
                if (model != null)
                {
                    menu.Code = $"{firstSpell}{DateTime.Now:yyMMddHHmmss}";
                }
                else
                {
                    menu.Code = fullSpell;
                }
            }
            else
            {
                menu.Code = firstSpell;
            }
            menu.Code = viewModel.Code;
            viewModel.Id = menu.Id;
            MenuService.Add(menu);
            return ServiceResponse<MenuViewModel>.SuccessResponse("success", viewModel);
        }

        /// <summary>
        /// 更新菜单
        /// </summary>
        [HttpPost, Route("api/menu/UpdateMenu")]
        public ServiceResponse<MenuViewModel> UpdateMenu(MenuViewModel viewModel)
        {
            var menu = MenuService.Find(m => m.Id == viewModel.Id);
            menu.Affix = viewModel.Meta.Affix;
            menu.Component = viewModel.Component;
            menu.Icon = viewModel.Meta.Icon;
            menu.IsDelete = false;
            menu.IsUsed = !viewModel.Hidden;
            menu.NoCache = viewModel.Meta.NoCache;
            menu.ParentId = viewModel.ParentId;
            menu.Path = viewModel.Path;
            menu.Title = viewModel.Title;
            menu.Type = viewModel.Type;
            menu.Sort = viewModel.Sort;
            menu.Redirect = viewModel.Redirect;
            menu.ModifyTime = DateTime.Now;
            menu.Modifyer = CurrentUserModel.LoginName;

            menu.Code = viewModel.Code;

            MenuService.Update(menu);
            return ServiceResponse<MenuViewModel>.SuccessResponse("success", viewModel);
        }

        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <param name="id">菜单id</param>
        [HttpGet, Route("api/menu/DeleteMenu")]
        public ServiceResponse<bool> DeleteMenu(Guid id)
        {
            var menu = MenuService.Find(m => !m.IsDelete && m.Id == id);
            menu.IsDelete = true;
            MenuService.Update(menu);
            return ServiceResponse<bool>.SuccessResponse("success", true);
        }

        /// <summary>
        /// 构造层级菜单
        /// </summary>
        private void GetMenuViewModels(List<MenuViewModel> viewModels, List<EMenu> models, Guid parentId)
        {
            var subList = models.Where(m => m.ParentId == parentId).OrderBy(m => m.Sort).ToList();
            foreach (var menu in subList)
            {
                var viewModel = new MenuViewModel
                {
                    Id = menu.Id,
                    Component = menu.Component,
                    Name = menu.Name,
                    Title = menu.Title,
                    Path = menu.Path,
                    Redirect = menu.Redirect,
                    Code = menu.Code,
                    Type = menu.Type,
                    Sort = menu.Sort,
                    Meta = new MetaModel
                    {
                        Title = menu.Title,
                        Icon = menu.Icon,
                        Roles = new List<string> { "admin" },
                        Affix = menu.Affix,
                        NoCache = menu.NoCache
                    },
                    Hidden = !menu.IsUsed,
                    ParentId = parentId,
                    ParentName = models.FirstOrDefault(m => m.Id == parentId)?.Title ?? ""
                };
                GetMenuViewModels(viewModel.Children, models, viewModel.Id);
                if (!viewModel.Children.Any())
                    viewModel.Children = null;
                viewModels.Add(viewModel);
            }
        }

        /// <summary>
        /// 获取菜单的用户id列表
        /// </summary>
        [HttpGet, Route("api/menu/GetMenuUser")]
        public ServiceResponse<List<string>> GetMenuUser(Guid menuId)
        {
            var rums = rMenuUrService.FindList(r => r.MenuId == menuId && !r.IsDelete).Select(r => r.KeyId).Distinct().ToList();
            var users = userService.FindList(u => !u.IsDelete && rums.Contains(u.UserID)).Select(u => u.LoginName).Distinct().ToList();
            //var ru = roleUserService.FindList(r => rums.Contains(r.RoleID)).Select(r => r.LoginName).Distinct().ToList();
            //users.AddRange(ru);
            //users = users.Distinct().ToList();

            return ServiceResponse<List<string>>.SuccessResponse(users);
        }

        /// <summary>
        /// 为菜单分配用户
        /// </summary>
        [HttpPost, Route("api/menu/HandleMenuUser")]
        public ServiceResponse<bool> HandleMenuUser(HandleMenuUserViewModel viewModel)
        {
            /**
             1.获取与该菜单关联的所有记录
             2.把id与用户表关联出用户id
             3.通过用户id与菜单id获取要删除的记录列表
             4.获取这个菜单的所有父节点
             5.把新的关联关系插入到数据库
             */
            var rList = rMenuUrService.FindList(r => r.MenuId == viewModel.MenuId).ToList();
            if (rList.Any())
            {
                var keyIds = rList.Select(r => r.KeyId).ToList();
                var userIds = userService.FindList(u => !u.IsDelete && keyIds.Contains(u.UserID)).Select(u => u.UserID).ToList();
                var deleteList = rMenuUrService.FindList(r => userIds.Contains(r.KeyId) && r.MenuId == viewModel.MenuId).ToList();
                if (deleteList.Any())
                    rMenuUrService.Deletes(deleteList);
            }
            var menuList = MenuService.GetParentMenusById(viewModel.MenuId);
            var subMenuList = MenuService.GetSubMenusById(viewModel.MenuId);
            var rMenuUr = new List<RMenuUR>();
            if (viewModel.Users != null && viewModel.Users.Any())
            {
                foreach (var user in viewModel.Users)
                {
                    foreach (var eMenu in menuList)
                    {
                        var r = new RMenuUR
                        {
                            Id = GuidUtil.NewSequentialId(),
                            KeyId = user.UserId,
                            CreateTime = DateTime.Now,
                            IsDelete = false,
                            IsHalfChecked = true,
                            IsUsed = true,
                            MenuId = eMenu.Id
                        };
                        if (eMenu.Id == viewModel.MenuId)
                            r.IsHalfChecked = false;
                        rMenuUr.Add(r);
                    }
                    foreach (var eMenu in subMenuList)
                    {
                        var r = new RMenuUR
                        {
                            Id = GuidUtil.NewSequentialId(),
                            KeyId = user.UserId,
                            CreateTime = DateTime.Now,
                            IsDelete = false,
                            IsHalfChecked = true,
                            IsUsed = true,
                            MenuId = eMenu.Id
                        };
                        if (eMenu.Id == viewModel.MenuId)
                            continue;
                        rMenuUr.Add(r);
                    }
                }
            }
            rMenuUrService.Adds(rMenuUr);

            return ServiceResponse<bool>.SuccessResponse(true);
        }

        /// <summary>
        /// 获取菜单分配的角色id列表
        /// </summary>
        [HttpGet, Route("api/menu/GetMenuRole")]
        public ServiceResponse<List<Guid>> GetMenuRole(Guid menuId)
        {
            var rums = rMenuUrService.FindList(r => r.MenuId == menuId && !r.IsDelete).Select(r => r.KeyId).Distinct().ToList();
            var roles = roleService.FindList(u => !u.IsDelete && rums.Contains(u.RoleID)).Select(r => r.RoleID).ToList();

            return ServiceResponse<List<Guid>>.SuccessResponse(roles);
        }

        /// <summary>
        /// 为菜单分配角色
        /// </summary>
        [HttpPost, Route("api/menu/HandleMenuRole")]
        public ServiceResponse<bool> HandleMenuRole(HandleMenuRoleViewModel viewModel)
        {
            var rList = rMenuUrService.FindList(r => r.MenuId == viewModel.MenuId).ToList();
            if (rList.Any())
            {
                var keyIds = rList.Select(r => r.KeyId).ToList();
                var roleIds = roleService.FindList(u => !u.IsDelete && keyIds.Contains(u.RoleID)).Select(u => u.RoleID).ToList();
                var deleteList = rMenuUrService.FindList(r => roleIds.Contains(r.KeyId) && r.MenuId == viewModel.MenuId).ToList();
                if (deleteList.Any())
                    rMenuUrService.Deletes(deleteList);
            }
            var menuList = MenuService.GetParentMenusById(viewModel.MenuId);
            var subMenuList = MenuService.GetSubMenusById(viewModel.MenuId);
            var rMenuUr = new List<RMenuUR>();
            if (viewModel.RoleIds != null && viewModel.RoleIds.Any())
            {
                foreach (var roleId in viewModel.RoleIds)
                {
                    foreach (var eMenu in menuList)
                    {
                        var r = new RMenuUR
                        {
                            Id = GuidUtil.NewSequentialId(),
                            KeyId = roleId,
                            CreateTime = DateTime.Now,
                            IsDelete = false,
                            IsHalfChecked = true,
                            IsUsed = true,
                            MenuId = eMenu.Id
                        };
                        if (eMenu.Id == viewModel.MenuId)
                            r.IsHalfChecked = false;
                        rMenuUr.Add(r);
                    }
                    foreach (var eMenu in subMenuList)
                    {
                        var r = new RMenuUR
                        {
                            Id = GuidUtil.NewSequentialId(),
                            KeyId = roleId,
                            CreateTime = DateTime.Now,
                            IsDelete = false,
                            IsHalfChecked = true,
                            IsUsed = true,
                            MenuId = eMenu.Id
                        };
                        if (eMenu.Id == viewModel.MenuId)
                            continue;
                        rMenuUr.Add(r);
                    }
                }
            }
            rMenuUrService.Adds(rMenuUr);

            return ServiceResponse<bool>.SuccessResponse(true);
        }

        /// <summary>
        /// 获取平台列表
        /// </summary>
        [HttpGet, Route("api/menu/GetPlatformList")]
        public ServiceResponse<List<MenuViewModel>> GetPlatformList()
        {
            var ls = MenuService.FindList(m => !m.IsDelete && m.ParentId == Guid.Empty).ToList();
            var viewModels = new List<MenuViewModel>();
            foreach (var menu in ls)
            {
                var viewModel = new MenuViewModel
                {
                    Id = menu.Id,
                    Component = menu.Component,
                    Name = menu.Name,
                    Title = menu.Title,
                    Path = menu.Path,
                    Redirect = menu.Redirect,
                    Code = menu.Code,
                    Type = menu.Type,
                    Sort = menu.Sort,
                    Meta = new MetaModel
                    {
                        Title = menu.Title,
                        Icon = menu.Icon,
                        Roles = new List<string> { "admin" },
                        Affix = menu.Affix,
                        NoCache = menu.NoCache
                    },
                    Hidden = !menu.IsUsed,
                    ParentId = Guid.Empty,
                    ParentName = "/"
                };
                viewModels.Add(viewModel);
            }

            return ServiceResponse<List<MenuViewModel>>.SuccessResponse(CommonConst.OprateSuccessStr, viewModels);
        }

    }
}